package cn.lisens.demo.service;

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.time.Instant;
import java.util.concurrent.CompletableFuture;

public class AuthorizationClient {

    private static class TokenCache {
        String token;
        long time;

        public TokenCache(String token, long time) {
            this.token = token;
            this.time = time;
        }
    }

    private final WebClient client;
    private final String user;
    private final String password;

    private final String uri;
    private CompletableFuture<TokenCache> tokenCacheFuture = CompletableFuture.completedFuture(new TokenCache(null, Instant.now().getEpochSecond()));

    public AuthorizationClient(final String baseUrl, final String uri, final String user, final String password) {
        this.user = user;
        this.password = password;
        this.uri = uri;
        this.client = WebClient.builder()
                .baseUrl(baseUrl)
                .build();
    }

    public Mono<String> getToken() {
        return Mono.defer(() -> {
              this.invalidate();
              return Mono.fromFuture(this.tokenCacheFuture)
                          .map(tokenCache -> tokenCache.token);
        });
    }

    private synchronized void invalidate() {
//      this.tokenCacheFuture = Mono.fromFuture(this.tokenCacheFuture)
//              .flatMap(tokenCache -> {
//                      if (Instant.now().getEpochSecond() - tokenCache.time < 1 && tokenCache.token != null) {
//                          return Mono.just(tokenCache);
//                      }
//                      return this.client.post()
//                              .uri(this.uri)
//                              .header("Content-Type", "application/json")
//                              .bodyValue(String.format("{\"user\":\"%s\", \"password\":\"%s\"}", user, password))
//                              .retrieve()
//                              .bodyToMono(String.class)
//                              .map(String::charAt);
////                              .map(LoginResponse::jwt)
////                              .map(jwt ->  new TokenCache(jwt, Instant.now().getEpochSecond()));
//                  }).toFuture();
    }
}
